<!DOCTYPE html>
<html><head><meta charset="UTF-8">
<style>
.ctab {
	margin-left: auto;
	margin-right: auto;
	border: 1px solid gray;
}
.ctab td, .ctab th {
	padding: 3px;
	border: 1px solid gray;
}
</style>
<title>Project IceStorm &ndash; Bitstream File Format Documentation</title>
</head><body>
<h1>Project IceStorm &ndash; Bitstream File Format Documentation</h1>

<p>
<i><a href=".">Project IceStorm</a> aims at documenting the bitstream format of Lattice iCE40
FPGAs and providing simple tools for analyzing and creating bitstream files.
This is work in progress.</i>
</p>

<h2>General Description of the File Format</h2>

<p>
The bitstream file starts with the bytes 0xFF 0x00, followed by a sequence of
zero-terminated comment strings, followed by 0x00 0xFF. However, there seems to be
a bug in the Lattice "bitstream" tool that moves the terminating 0x00 0xFF a few
bytes into the comment string in some cases.
</p>

<p>
After the comment sections the token 0x7EAA997E (MSB first) starts the actual
bit stream. The bitstream consists of one-byte commands, followed by a payload
word, followed by an optional block of data. The MSB nibble of the command byte
is the command opcode, the LSB nibble is the length of the command payload in
bytes. The commands that do not require a payload are using the opcode 0, with
the command encoded in the payload field. Note that this "payload" in this
context refers to a single integer argument, not the blocks of data that
follows the command in case of the CRAM and BRAM commands.
</p>

<p>
The following commands are known:
</p>

<table class="ctab">
<tr><th>Opcode</th><th>Description</th></tr>
<tr><td>0</td><td>payload=1: CRAM Data<br/>
                  payload=3: BRAM Data<br/>
		  payload=5: Reset CRC<br/>
		  payload=6: Wakeup<br/>
		  payload=8: Reboot</td></tr>
<tr><td>1</td><td>Set bank number</td></tr>
<tr><td>2</td><td>CRC check</td></tr>
<tr><td>4</td><td>Set boot address</td></tr>
<tr><td>5</td><td>Set internal oscillator frequency range<br/>
                  payload=0: low<br/>
                  payload=1: medium<br/>
                  payload=2: high</td></tr>
<tr><td>6</td><td>Set bank width</td></tr>
<tr><td>7</td><td>Set bank height</td></tr>
<tr><td>8</td><td>Set bank offset</td></tr>
<tr><td>9</td><td>payload=0: Disable warm boot<br/>
                  payload=16: Enable cold boot<br/>
                  payload=32: Enable warm boot</td></tr>
</table>

<p>
Use <span style="font-family:monospace">iceunpack -vv</span> to display the commands as they are interpreted by the tool.
</p>

<p>
Note: The format itself seems to be very flexible. At the moment it is unclear what the FPGA
devices will do when presented with a bitstream that use the commands in a different way
than the bitstreams generated by the lattice tools.
</p>

<h2>Writing SRAM content</h2>

<p>
Most bytes in the bitstream are SRAM data bytes that should be written to the various SRAM banks
in the FPGA. The following sequence is used to program an SRAM cell:
</p>

<ul>
<li>Set bank width (opcode 6)</li>
<li>Set bank height (opcode 7)</li>
<li>Set bank offset (opcode 8)</li>
<li>Set bank number (opcode 1)</li>
<li>CRAM or BRAM Data Command</li>
<li>(width * height / 8) data bytes</li>
<li>two zero bytes</li>
</ul>

<p>
The bank width and height parameters reflect the width and height of the SRAM bank. A large SRAM can
be written in smaller chunks. In this case height parameter may be smaller and the offset parameter
reflects the vertical start position.
</p>

<p>
There are four CRAM and four BRAM banks in an iCE40 FPGA. The different devices from the family
use different widths and heights, but the same number of banks.
</p>

<p>
The CRAM banks hold the configuration bits for the FPGA fabric and hard IP blocks, the BRAM
corresponds to the contents of the block ram resources.
</p>

<p>
The ordering of the data bits is in MSB first row-major order.
</p>

<h2>Organization of the CRAM</h2>

<p><a href="checkerboard.png"><img alt="Mapping of tile config bits to 2D CRAM"
style="float:right; padding:1em; padding-top:0; border:0" height="200" src="checkerboard.png"></a></p>

<p>
The chip is organized into four quadrants. Each CRAM memory bank contains the configuration bits for one quadrant.
The address 0 is always the corner of the quadrant, i.e. in one quadrant the bit addresses increase with the tile x/y
coordinates, in another they increase with the tile x coordinate but decrease with the tile y coordinate, and so on.
</p>

<p>
For an iCE40 1k device, that has 12 x 16 tiles (not counting the io tiles), the CRAM bank 0 is the one containing the corner tile (1 1),
the CRAM bank 1 contains the corner tile (1 16), the CRAM bank 2 contains the corner tile (12 1) and the CRAM bank 3 contains the
corner tile (12 16). The entire CRAM of such a device is depicted on the right (bank 0 is in the lower left corner in blue/green).
</p>

<p>
The checkerboard pattern in the picture visualizes which bits are associated
with which tile. The height of the configuration block is 16 for all tile
types, but the width is different for each tile type. IO tiles have
configurations that are 18 bits wide, LOGIC tiles are 54 bits wide, and
RAM tiles are 42 bits wide. (Notice the two slightly smaller columns for the RAM tiles.)
</p>

<p>
The IO tiles on the top and bottom of the chip use a strange permutation pattern for their bits. It can be seen in the picture that
their columns are spread out horizontally. What cannot be seen in the picture is the columns also are not in order and the bit
positions are vertically permuted as well. The <span style="font-family:monospace">CramIndexConverter</span> class in <span style="font-family:monospace">icepack.cc</span> encapsulates the calculations
that are necessary to convert between tile-relative bit addresses and CRAM bank-relative bit addresses.
</p>

<p>
The black pixels in the image correspond to CRAM bits that are not associated with any IO, LOGIC or RAM tile.
Some of them are unused, others are used by hard IPs or other global resources. The <span style="font-family:monospace">iceunpack</span> tool reports
such bits, when set, with the "<span style="font-family:monospace">.extra_bit <i>bank x y</i></span>" statement in the ASCII output format.
</p>

<h2>Organization of the BRAM</h2>

<p>
This part of the documentation has not been written yet.
</p>

<h2>CRC Check</h2>

<p>
The CRC is a 16 bit CRC. The (truncated) polynomial is 0x1021 (CRC-16-CCITT). The "Reset CRC" command sets
the CRC to 0xFFFF. No zero padding is performed.
</p>

</body></html>
